package com.dataseek.iot.mqtt.handler;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.dataseek.iot.mysql.entity.Device;
import com.dataseek.iot.mysql.entity.DeviceLog;
import com.dataseek.iot.mysql.entity.DeviceRecord;
import com.dataseek.iot.mysql.entity.User;
import com.dataseek.iot.mysql.mapper.DeviceMapper;
import com.dataseek.iot.mysql.mapper.MyDeviceMapper;
import com.dataseek.iot.mysql.service.IAlarmLogService;
import com.dataseek.iot.mysql.service.IDeviceParamsService;
import com.dataseek.iot.mysql.service.impl.DeviceServiceImpl;
import com.dataseek.iot.mysql.service.impl.UserServiceImpl;
import com.dataseek.iot.notice.domain.ToEmail;
import com.dataseek.iot.notice.service.EmailService;
import com.dataseek.iot.notice.service.TencentSmsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author cc
 * @Title: 消息处理handler
 * @Description: 消息处理handler
 * @date 2021/10/62:10 下午
 * @since 1.0
 */
@Service
@Slf4j
public class MessageHandler {

    @Autowired
    IDeviceParamsService deviceParamsService;

    @Autowired
    IAlarmLogService alarmLogService;

    @Autowired
    DeviceMapper deviceMapper;

    @Autowired
    MyDeviceMapper myDeviceMapper;

    @Autowired
    EmailService emailService;

    @Autowired
    TencentSmsService tencentSmsService;

    @Autowired
    DeviceServiceImpl deviceService;

    @Autowired
    UserServiceImpl userService;



    /**
     * 设备参数处理
     * @param productCode
     * @param deviceCode
     * @param data
     */
    public void handleDeviceParams(String productCode, String deviceCode, String data){
        // 存储数据
        Boolean state = deviceParamsService.save(parseDeviceParams(productCode, deviceCode, data));

        //发送邮件
        noticeUsers(deviceCode, "设备参数信息", data);
    }

    /**
     * 报警日志处理
     * @param productCode
     * @param deviceCode
     * @param data
     */
    public void handleAlarmLog(String productCode, String deviceCode, String data, String msg){
        parseAlarmLog(productCode, deviceCode, data);
        //存储数据
        alarmLogService.save(parseAlarmLog(productCode,  deviceCode,  data));
        //发送邮件
        noticeUsers(deviceCode, "设备报警信息", msg);
        //TODO 向用户发送短信
    }

    /**
     * 设备功能日志通知
     * @param productCode
     * @param deviceCode
     * @param data
     */
    public void handleFunctionLog(String productCode, String deviceCode, String data){
        log.info("功能日志来源于 {},{}，内容如下：{}", productCode, deviceCode, data);
        noticeUsers(deviceCode, "设备远控信息如下:", data);
    }

    /**
     * 设备运行正常通知
     * @param deviceCode
     * @param data
     */
    public void handleNormalLog(String deviceCode, String data){
        log.info("设备运行日志信息:{}", data);
    }

    /**
     * 设备离线通知
     * @param deviceCode
     * @param data
     */
    public void handleDisconnectedLog(String deviceCode,  String data){
        log.info("clientId 为 {} 的设备离线", deviceCode);
        noticeUsers(deviceCode, "clientId 为 "+ deviceCode+" 的设备离线", data);
    }

    /**
     * 设备上线通知
     * @param deviceCode
     * @param data
     */
    public void handleConnectedLog(String deviceCode, String data){
        log.info("clientId 为 {} 的设备上线", deviceCode);
        noticeUsers(deviceCode, "clientId 为 "+ deviceCode+" 的设备上线", data);
    }
    /**
     * 获取用户通信方式
     * @param deviceCode
     */
    private  void  noticeUsers(String deviceCode, String subject, String content){
        List<String> mails = new ArrayList<>();
        List<String> tels  = new ArrayList<>();

        Device device = deviceService.getDeviceByCode(deviceCode);
        String lineCode = device.getLineCode();
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.like("line_code", lineCode);
        List<User> users = userService.list(queryWrapper);
        if(users.size()==0){
            return;
        }
        for(User u : users){
            mails.add(u.getMail());
            tels.add(u.getTel());
        }

        //TODO 邮件模板要定制
        ToEmail toEmail = new ToEmail();
        toEmail.setTos(mails.toArray(new String[mails.size()]));
        toEmail.setSubject(subject);
        toEmail.setContent(content);
        emailService.sendEmail(toEmail);
        //TODO  向用户发送短信

    }

    /**
     * 解析设备参数
     * @param productCode
     * @param deviceCode
     * @param data
     * @return
     */
    public  DeviceRecord parseDeviceParams(String productCode, String deviceCode, String data){
        List<String> codes = deviceService.getDictNames(deviceCode,false);
        JSONObject jo = JSON.parseObject(data);
        DeviceRecord record;
        JSONObject json = new JSONObject();
        json.put("productCode", productCode);
        json.put("deviceCode", deviceCode);
        if(Objects.isNull(jo.getString("messageId"))){
            log.error("关键参数为空,{}", "messageId");
            return null;
        };
        json.put("messageId", jo.getString("messageId"));
        json.put("timestamp", jo.getString("timestamp"));
        JSONObject props = jo.getJSONObject("properties");
        if(Objects.isNull(jo.getJSONObject("properties"))){
            log.error("关键参数为空, {}", "properties");
            return null;
        }
        if(Objects.isNull(codes)){
            log.error("未查询到与设备编码相关的属性数据");
            return null;
        }
        for(String code : codes){
            if(Objects.nonNull(props.get(code))){
                json.put(code, props.get(code));
                if(code.equals("In")){
                    json.put("Inn",props.get(code));
                }else {
                    json.put(code, props.get(code));
                }
            }
        }
        record = json.toJavaObject(DeviceRecord.class);
        return record;
    }

    /**
     * 解析报警日志
     * @param productId
     * @param deviceId
     * @param data
     * @return
     */
    private static DeviceLog parseAlarmLog(String productId, String deviceId, String data){
        log.info("订阅到的日志信息为：{}", data);
        JSONObject jo = JSON.parseObject(data);
        DeviceLog log = new DeviceLog();
        JSONObject d = jo.getJSONObject("data");
        log.setProductCode(productId);
        log.setDeviceCode(deviceId);

        log.setMessageId(jo.getString("messageId"));
        log.setAlarmName(d.getString("name"));
        log.setAlarmType(d.getString("alarmType"));
        log.setAlarmValue(d.getString("value"));
        log.setTimestamp(d.getBigDecimal("time"));
        return log;
    }

    //TODO
    private static DeviceRecord parseDeviceAlarm(String productCode, String deviceCode, String data){
        JSONObject jo = JSON.parseObject(data);
        DeviceRecord params= new DeviceRecord();
        params.setProductCode(productCode);
        params.setDeviceCode(deviceCode);
        if(jo.containsKey("properties")){
            params.setBattery(jo.getBigDecimal("battery"));
        }

        return null;
    }


}
